package fr.mywiki.model.ejbAdapter;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;

import fr.mywiki.model.ejbAdapter.utils.PersistenceException;


/**
 * This class permits the data access. It centralizes all methods which are implemented in the
 * <code>Value</code> class.
 * 
 * @author tlombard
 */
public class DataController {
	/** Private constructor : this class cannot be instanciated */
	private DataController() {
	}
	
	/**
	 * Creates and return a new <code>Value</code> object of the desired entity type.
	 * 
	 * @param typeEnt the type of the <code>Value</code> object to create.
	 * @return the created <code>Value</code> object.
	 */
	public static Value createValue(String typeEnt) throws PersistenceException, RemoteException {
		return ServicesFacade.getInstance().create(typeEnt);
	}
	
	/**
	 * Returns the <code>Value</code> object having the specified type and id. If there isn't such
	 * an element in the database, a <code>null</code> value is returned.
	 * 
	 * @param id a <code>Long</code> object, the identifier of the value.
	 * @param typeEnt the type of value.
	 * @return a <code>Value</code> object.
	 * @throws RemoteException 
	 */
	public static Value getValue(Long id, String typeEnt) throws RemoteException {
		try {
			return ServicesFacade.getInstance().getValue(id,typeEnt);
		} catch (ObjectNotFoundException e) {
			return null;
		}
	}
	
	/**
	 * Computes and returns the list of <code>Value</code> objects corresponding to the
	 * identifiers given in parameter and the specified type. They are in the same order as the original list.
	 * 
	 * @param ids a <code>Collection</code> of <code>Long</code> objects.
	 * @param type the type of data to retrieve.
	 * @return a <code>Collection</code> of <code>value</code> objects.
	 * @throws RemoteException 
	 */
	public static Collection getValues(Collection ids, String type) throws RemoteException {
		ArrayList values = new ArrayList();
		Iterator itIds = ids.iterator();
		while(itIds.hasNext())
			values.add(getValue((Long)itIds.next(),type));
		return values;
	}
	
	/**
	 * Finds and returns all the <code>Value</code> objects of the desired type.
	 * 
	 * @param typeEnt the type of desired data
	 * @return a <code>Collection</code> of <code>Value</code> objects.
	 * @throws RemoteException 
	 */
	public static Collection findAll(String typeEnt) throws RemoteException {
		return ServicesFacade.getInstance().findAll(typeEnt);
	}
	
	/**
	 * Computes and returns the list of identifiers of a list of <code>Value</code> objects. They
	 * are in the same order as the original list.
	 * 
	 * @param values a <code>Collection</code> of <code>value</code> objects.
	 * @return a <code>Collection</code> of <code>Long</code> objects.
	 */
	public static Collection toIds(Collection values) {
		ArrayList ids = new ArrayList();
		Iterator itValues = values.iterator();
		while(itValues.hasNext())
			ids.add(((Value) itValues.next()).getId());
		return ids;
	}
	
	/**
	 * Removes the specified <code>Value</code> object from the database.
	 * 
	 * @param value a <code>Value</code> object.
	 * @throws ObjectNotFoundException if the object could not be found in the database.
	 * @throws RemoteException 
	 */
	public static void removeValue(Value value) throws ObjectNotFoundException, RemoteException {
		ServicesFacade.getInstance().remove(value);
		value = null;
	}
	
	/**
	 * Finds and returns all the <code>Value</code> objects linked to the one given in parameter
	 * via the specified relation.
	 * 
	 * @param relName the name of the considered relation.
	 * @param value a <code>Value</code> object.
	 * @return a <code>Collection</code> of <code>Value</code> objects.
	 * @throws RemoteException 
	 */
	public static Collection getLinks(String relName, Value value) throws RemoteException, FinderException {
		return ServicesFacade.getInstance().getLinks(value,relName);
	}
	
	/**
	 * Adds a new relation between two <code>Value</code> objects via the specified relation.
	 * 
	 * @param relName the name of the considered relation.
	 * @param from the <code>Value</code> object where the link <i>comes from</i>.
	 * @param to the <code>Value</code> object where the link <i>goes to</i>.
	 * @throws RemoteException 
	 */
	public static void addLink(String relName, Value from, Value to) throws RemoteException, FinderException {
		ServicesFacade.getInstance().addLink(from,to,relName);
	}
	
	/**
	 * Indicates if two <code>Value</code> objects are linked one to the other (in the specified
	 * order) via the given link.
	 * 
	 * @param from the <i>from</i> <code>Value</code> object.
	 * @param to the <i>to</i> <code>Value</code> object.
	 * @param relName the relation to consider.
	 * @return <code>true</code> if the two objects are linked, false otherwise.
	 * @throws RemoteException 
	 */
	public static boolean isLinked(Value from, Value to, String relName) throws RemoteException, FinderException {
		return getLinks(relName,from).contains(to);
	}
	
	/**
	 * Removes the relation between two <code>Value</code> objects, linked in a specified order
	 * via a given relation.
	 * 
	 * @param relName the relation to consider.
	 * @param from the <i>from</i> <code>Value</code> object.
	 * @param to the <i>to</i> <code>Value</code> object.
	 * @throws RemoteException 
	 */
	public static void removeLink(String relName, Value from, Value to) throws RemoteException, FinderException {
		ServicesFacade.getInstance().removeLink(from, to, relName);
	}
}
